/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package io.iec.edp.caf.autoconfigure;

import io.iec.edp.caf.autoconfigure.reader.YamlCheckUtil;
import io.iec.edp.caf.commons.runtime.CafEnvironment;
import io.iec.edp.caf.commons.utils.JarUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.loader.LaunchedURLClassLoader;
import sun.misc.URLClassPath;

import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;

@Slf4j
public class EnvironmentPreparedConfiguration {

    public static void environmentPrepared(){
        //放开
        checkYamlEnable();
        solveSystemProperties();
        middleWarePrepared();
    }

    /**
     * 判断yaml文件是否被修改
     * @return
     */
    private static boolean checkYamlEnable(){
        String yamlPath = CafEnvironment.getStartupPath()+System.getProperty("file.separator")+"application.yaml";

        //String yamlString = readToBuffer(yamlPath);
        //当不存在application.yaml文件时无须进行判断
        //if(yamlString==null||"".equals(yamlString)) return true;

        //如果yaml文件被修改了
        if(YamlCheckUtil.applicationYamlContentChanged()){
            log.error("检测到用户手动修改application.yaml文件，手动修改内容存在丢失风险，建议通过EMC进行配置的修改。");
            //System.exit(Status.INFO);
            //throw new RuntimeException("Application.yaml has bean changed by custom user, please check it out.");
        }
        return true;
    }

    /**
     * 对一些系统变量的处理添加和修改
     */
    private static void solveSystemProperties(){
        //获取配置
        String serverPath = System.getProperty("server.runtime.path.name","jstack");
        //获取runtime的父目录server目录
        File serverFile = new File(CafEnvironment.getStartupPath()).getParentFile();
        //与启动脚本中配置进行比较
        if(serverFile!=null&&serverFile.getName().equals(serverPath)) {
            //设置为全路径
            System.setProperty("server.runtime.path.name",serverFile.getAbsolutePath());
        }
        System.setProperty("caf.startup.server.path.name",serverPath);
    }

    /**
     * 启动前把中间件放入classloader中
     * 只有
     */
    static private void middleWarePrepared(){
        LaunchedURLClassLoader launchedURLClassLoader = (LaunchedURLClassLoader)Thread.currentThread().getContextClassLoader();
        String midName = System.getProperty("middleware.servlet", "none").toLowerCase();
        if(!midName.equals("none")){
            Path path = Paths.get(CafEnvironment.getStartupPath(), "middleware", "servlet", midName);
            URL[] urls = JarUtil.getJarPathFromDirPaths(path.toString());

            addUrl(launchedURLClassLoader,urls);
        }
    }

    private static void addUrl(LaunchedURLClassLoader launchedURLClassLoader, URL[] urls) {
        URLClassPath ucp;
        try {
            Field ucpField = URLClassLoader.class.getDeclaredField("ucp");
            ucpField.setAccessible(true);
            ucp = (URLClassPath) ucpField.get(launchedURLClassLoader);
            for (URL url : urls) {
                ucp.addURL(url);
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            log.error(e.getMessage(),e);
        }
    }

    private static String readToBuffer(String filePath){
        StringBuffer buffer = new StringBuffer();
        try {
            InputStream stream = null;
            BufferedReader reader = null;
            try {
                File file = new File(filePath);
                if (!file.exists())
                    return null;
                stream = new FileInputStream(file);
                String line; // 用来保存每行读取的内容
                reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
                line = reader.readLine(); // 读取第一行
                while (line != null) { // 如果 line 为空说明读完了
                    buffer.append(line); // 将读到的内容添加到 buffer 中
                    buffer.append("\n"); // 添加换行符
                    line = reader.readLine(); // 读取下一行
                }
            } finally {
                if (reader != null)
                    reader.close();
                if (stream != null)
                    stream.close();
            }
        } catch (IOException e) {
            log.error(e.getMessage(),e);
        }
        return buffer.toString();
    }
}
